<?php

namespace App\CustHub\Service;

use App\CustHub\Mapper\ActiveAddFriendMapper;
use App\CustHub\Model\ChAddFriendRobot;
use App\CustHub\Model\ChAddFriendTask;
use App\CustHub\Model\ChConfigValue;
use App\CustHub\Model\ChCorpTag;
use App\CustHub\Model\ChSmartTag;
use App\CustHub\Model\ChUser;
use Carbon\Carbon;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Paginator\LengthAwarePaginator;
use Mine\Abstracts\AbstractService;
use Mine\Annotation\Transaction;
use Mine\Exception\NormalStatusException;
use Mine\MineCollection;
use Mine\MineModel;
use Mine\MineResponse;
use PhpOffice\PhpSpreadsheet\IOFactory;
use Psr\Http\Message\ResponseInterface;

class ActiveAddFriendRecordService extends AbstractService
{
    #[Inject]
    protected ChSmartTag $smartTag;

    #[Inject]
    protected ActiveAddFriendService $activeAddFriendService;

    #[Inject]
    protected ChCorpTag $corpTag;

    #[Inject]
    protected ChConfigValue $config;

    #[Inject]
    protected ChAddFriendTask $task;

    #[Inject]
    protected ChUser $user;

    public $mapper;

    public function __construct(ActiveAddFriendMapper $mapper)
    {
        $this->mapper = $mapper;
    }

    function ensureArray($value): array
    {
        return isset($value) ? (is_array($value) ? $value : explode(',', $value)) : [];
    }

    public function checkIds($ids)
    {
        // 查询表中 status 为 1 的记录的 id
        $statusOneIds = $this->mapper->model::whereIn('id', $ids)
            ->where('status', 1)
            ->pluck('id')
            ->toArray();

        // 从 ids 中剔除 status 为 1 的 id
        $ids = array_diff($ids, $statusOneIds);

        return $ids;
    }

    public function filter($params): array
    {
        $uid = $params['uid'];

        // 获取配置值（是否启用重复过滤）
        $isFilter = $this->config::query()
                ->where('uid', $uid)
                ->where('config_id', 35)
                ->value('value') == 1;

        // 处理传入的手机号数组
        $mobiles = $this->ensureArray($params['mobiles']);

        $error = 0;   // 记录格式错误的手机号
        $repeat = 0;  // 记录重复的手机号
        $validMobiles = []; // 存储符合条件的手机号

        // 一次性查询数据库，减少查询次数
        $existingRecords = $this->mapper->model::where('uid', $uid)
            ->whereIn('mobile', $mobiles)
            ->get(['mobile', 'wechat_status'])
            ->keyBy('mobile'); // 变成键值对方便查找

        // 处理手机号数组
        foreach ($mobiles as $mobile) {
            // 1. 判断手机号是否是纯数字
            if (!ctype_digit($mobile)) {
                $error++;
                continue;
            }

            $existingRecord = $existingRecords[$mobile] ?? null;

            // 2. 判断是否需要过滤重复手机号
            if ($isFilter) {
                if ($existingRecord) {
                    $repeat++;
                    continue;
                }
            } else {
                if ($existingRecord) {
                    $status = $existingRecord->status;
                    $wechatStatus = $existingRecord->wechat_status;
                    if ($status == 0)
                    {
                        $repeat++; // 自动过滤
                        continue;
                    }
                    else {
                        if($wechatStatus == 2)
                        {
                            $repeat++;
                            continue;
                        }
                        if($wechatStatus == 0)
                        {
                            $data = [
                                'status' => 0,
                                'wechat_status' => null,
                                'add_robot_id' => null,
                            ];
                            $existingRecord->update($data);
                        }
                        if(in_array($wechatStatus,[1,3]))
                        {
                            $robotId = ChAddFriendRobot::where('uid', $uid)->where('id', $existingRecord->add_robot_id)->value('robot_id');
                            $this->activeAddFriendService->sendInvite((int)$robotId,$existingRecord);
                        }
                    }
                }
            }

            // 3. 通过所有检查，加入待插入数组
            $validMobiles[] = $mobile;
        }
        return [
            'error' => $error,
            'repeat' => $repeat,
            'validMobiles' => $validMobiles,
            'count' => count($mobiles)];
    }

    public function getTagJsons($params)
    {
        $result = [];

        if (array_key_exists('smart_tag_ids', $params)) {
            $smart_tag_ids = $this->ensureArray($params['smart_tag_ids']);
            $smart_tags_data = $this->smartTag::withoutGlobalScopes()->select(['id', 'name'])->whereIn('id', $smart_tag_ids)->get()->toArray();
            $result['smart_tags'] = !empty($smart_tags_data) ? json_encode($smart_tags_data) : null;
        }

        if (array_key_exists('corp_tag_ids', $params)) {
            $corp_tag_ids = $this->ensureArray($params['corp_tag_ids']);
            $corp_tags_data = $this->corpTag::query()->select(['id', 'name'])->whereIn('id', $corp_tag_ids)->get()->toArray();
            $result['corp_tags'] = !empty($corp_tags_data) ? json_encode($corp_tags_data) : null;
        }

        return $result;
    }

    #[Transaction]
    public function insertRecord($validMobiles,$params,$tags): void
    {
        $insertData = array_map(function ($mobile) use ($params, $tags) {
            return [
                'uid' => $params['uid'],
                'main_uid' => $params['main_uid']??null,
                'mobile' => $mobile,
                'corp_tags' => $tags['corp_tags']??null,
                'smart_tags' => $tags['smart_tags']??null,
                'status' => 0,
                'group_id' => $params['group_id'],
            ];
        }, $validMobiles);

        $this->mapper->model::insert($insertData);
    }

    public function recordList(array $params): array
    {
        $page = (int)$params['page'] ?? 1;
        $pageSize = (int)$params['page_size'] ?? MineModel::PAGE_SIZE;
        $list = $this->mapper->recordList($params)->get()->toArray();
        // 处理 corp_tags 和 smart_tags 字段
        foreach ($list as &$item) {
            if (isset($item->corp_tags)) {
                $decodedCorpTags = json_decode($item->corp_tags, true);
                if (json_last_error() === JSON_ERROR_NONE) {
                    $item->corp_tags = $decodedCorpTags;
                } else {
                    $item->corp_tags = [];
                }
            }
            if (isset($item->smart_tags)) {
                $decodedSmartTags = json_decode($item->smart_tags, true);
                if (json_last_error() === JSON_ERROR_NONE) {
                    $item->smart_tags = $decodedSmartTags;
                } else {
                    $item->smart_tags = [];
                }
            }
        }
        unset($item);
        $offset = ($page - 1) * $pageSize;
        $paginatedItems = array_slice($list, $offset, $pageSize);

        $paginate = new LengthAwarePaginator(
            $paginatedItems,
            count($list),
            $pageSize,
            $page
        );

        return $this->mapper->setPaginate($paginate);
    }

    public function taskList(array $params): array
    {
        $list = $this->task::query()
            ->select(['id','file_name','status','editor','created_at'])
            ->where('uid', $params['uid'])
            ->when(isset($params['status']), function ($query) use ($params) {
                $query->where('status', $params['status']);
            })
            ->when(!empty($params['created_at']), function ($query) use ($params) {
                $range = explode(',', $params['created_at']);
                if (count($range) === 2) {
                    $query->whereBetween('created_at', [$range[0], $range[1]]);
                }
            })
            ->orderBy('created_at', 'desc')
            ->paginate((int)$params['page_size']??MineModel::PAGE_SIZE);

        return $this->mapper->setPaginate($list);
    }

    #[Transaction]
    public function saveRecord(array $params): bool
    {
        $result = $this->filter($params);
        $tags = $this->getTagJsons($params);
        // 若筛选完后无合法手机号，返回错误信息
        if (empty($result['validMobiles'])) {
            throw new NormalStatusException("共".$result['count']."条消息，重复".$result['repeat']."条，格式错误".$result['error']."条");
        }

        $this->insertRecord($result['validMobiles'], $params,$tags);

        return true;
    }

    #[Transaction]
    public function importSaveRecord($file, array $params): bool
    {
        // 获取文件名、编辑者
        $fileName = $file->getClientFilename();
        $editor = $this->user::query()
            ->where('id', $params['uid'])
            ->value('nickname');

        // 插入任务记录并获取 ID
        $insertedId = $this->task::insertGetId([
            'uid'       => $params['uid'],
            'main_uid'  => $params['main_uid'],
            'status'    => 0,
            'file_name' => $fileName,
            'editor'    => $editor,
        ]);

        // 读取 Excel 数据
        $tempFilePath = $file->getRealPath();
        $spreadsheet = IOFactory::load($tempFilePath);
        $sheet = $spreadsheet->getActiveSheet();

        // 读取 A 列手机号（从第 2 行开始）
        $phoneNumbers = [];
        foreach ($sheet->getRowIterator(2) as $row) {
            $cell = $sheet->getCell('A' . $row->getRowIndex())->getValue();
            if ($cell !== null && ctype_digit($cell)) { // 确保是纯数字
                $phoneNumbers[] = $cell;
            }
        }

        // 过滤手机号并插入数据
        if (!empty($phoneNumbers)) {
            $params['mobiles'] = $phoneNumbers;
            $result = $this->filter($params);
            $tags = $this->getTagJsons($params);

            if (!empty($result['validMobiles'])) {
                $this->insertRecord($result['validMobiles'], $params,$tags);
            }
        }

        // 更新任务状态
        $this->task::where('id', $insertedId)->update(['status' => 1]);

        return true;
    }

    public function setTags($params): bool
    {
        $tags = $this->getTagJsons($params);
        $ids = $this->ensureArray($params['ids']);
        $ids = $this->checkIds($ids);
        if (empty($ids)) {
            throw new NormalStatusException("没有符合条件的手机号，请重新选择");
        }
        $this->mapper->model::whereIn('id', $ids)->update($tags);
        return true;
    }

    public function deleteRecord(array $params): bool
    {
        $ids = $this->ensureArray($params['ids']);
        $ids = $this->checkIds($ids);
        if (empty($ids)) {
            throw new NormalStatusException("没有符合条件的手机号，请重新选择");
        }
        $this->mapper->model::whereIn('id', $ids)->delete();
        return true;
    }

    public function exportRecord(array $params, ?string $dto, ?string $filename = null, ?\Closure $callbackData = null): ResponseInterface
    {
        if (empty($dto)) {
            return container()->get(MineResponse::class)->error('导出未指定DTO');
        }

        if (empty($filename)) {
            $filename = "主动加好友-手机号" . Carbon::now()->format('Y-m-d_H-i-s') . ".xlsx";
        }

        $query = $this->mapper->recordList($params);

        $list = $query->get();

        // 数据转换
        $list->transform(function ($item) {
            return[
                'mobile' => $item->mobile,
                'created_at' => $item->created_at,
                'corp_name' => $item->corp_name ?? '',
                'add_robot_id' => $item->add_robot_id ?? '',
                'nickname' => $item->robot_nickname ?? '',
                'status_text' => [
                        0 => '未执行',
                        1 => '已完成',
                        2 => '已失败'
                    ][$item->status] ?? '未知',
                'add_time' => $item->add_time,
                'wechat_status_text' => [
                        0 => '待分配',
                        1 => '未找到微信号',
                        2 => '待通过',
                        3 => '已通过',
                        4 => '已拒绝'
                    ][$item->wechat_status] ?? '--',
                'pass_time' => $item->pass_time ?? '',
                'add_number' => $item->add_number ?? '',
                'content' => $item->content ?? '',
            ];
        });

        // 执行导出
        return (new MineCollection())->export($dto, $filename, $list->toArray(), $callbackData);
    }

    public function dailyData(array $params)
    {

        $pageSize = (int)($params['page_size'] ??MineModel::PAGE_SIZE);
        $query = $this->mapper->dailyData($params);
        $list = $query->paginate($pageSize);

        return $this->mapper->setPaginate($list);
    }

    public function exportDailyData(array $params,?string $dto, ?string $filename = null)
    {
        if (empty($dto)) {
            return container()->get(MineResponse::class)->error('导出未指定DTO');
        }
        if (empty($filename)) {
            $filename = "主动加好友-分日数据" . Carbon::now()->format('Y-m-d_H-i-s') . ".xlsx";
        }

        // 调用 dailyData 方法获取数据
        $query = $this->mapper->dailyData($params);
        $list = $query->get();

        // 数据转换
        $list->transform(function ($item) {
            return [
                'date' => $item->date,
                'total_greetings' => $item->total_greetings,
                'passed_friends' => $item->passed_friends,
                'pass_rate' => $item->pass_rate . '%', // 转换为百分比格式
                'not_found_wechat' => $item->not_found_wechat,
            ];
        });

        // 执行导出
        return (new MineCollection())->export($dto, $filename, $list->toArray());
    }

}